package jdklearning.concurrent.threadpool;


import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolExecutorLearning {

	
    public static void main(String[] args) throws Exception {
    	ThreadPoolExecutorLearning threadPoolExecutorLearning = new ThreadPoolExecutorLearning();
    	threadPoolExecutorLearning.discardOldestPolicy();
    }  
	
    
    /**
     * 将”线程池的拒绝策略”由DiscardPolicy修改为AbortPolicy之后，
     * 当有任务添加到线程池被拒绝时，会抛出RejectedExecutionException。
     */
    public void abortPolicyDemo() {
    	
    	final int THREADS_SIZE = 1;  
        final int CAPACITY = 1;  


        // 创建线程池。线程池的"最大池大小"和"核心池大小"都为1(THREADS_SIZE)，"线程池"的阻塞队列容量为1(CAPACITY)。  
        ThreadPoolExecutor pool = new ThreadPoolExecutor(THREADS_SIZE, THREADS_SIZE, 0, TimeUnit.SECONDS,  
                new ArrayBlockingQueue<Runnable>(CAPACITY));  
        // 设置线程池的拒绝策略为"抛出异常"  
        pool.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());  

        try {  

            // 新建10个任务，并将它们添加到线程池中。  
            for (int i = 0; i < 10; i++) {  
                Runnable myrun = new MyRunnable("task-" + i);
                pool.execute(myrun);  
            }  
        } catch (RejectedExecutionException e) {  
            e.printStackTrace();  
            // 关闭线程池  
            pool.shutdown();  
        }  
    	
    }
	
	
    
    /**
     *  示例(也是丢弃任务，但是不抛出异常。)
     */
    public void discardPolicy() {
    	
    	final int THREADS_SIZE = 1;  
        final int CAPACITY = 1;  

        // 创建线程池。线程池的"最大池大小"和"核心池大小"都为1(THREADS_SIZE)，"线程池"的阻塞队列容量为1(CAPACITY)。  
        ThreadPoolExecutor pool = new ThreadPoolExecutor(THREADS_SIZE, THREADS_SIZE, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(CAPACITY));  
        // 设置线程池的拒绝策略为"丢弃"  
        
        /**
         * 线程池pool的”最大池大小”和”核心池大小”都为1(THREADS_SIZE)，这意味着”线程池能同时运行的任务数量最大只能是1”。
		线程池pool的阻塞队列是ArrayBlockingQueue，ArrayBlockingQueue是一个有界的阻塞队列，ArrayBlockingQueue的容量为1。
		这也意味着线程池的阻塞队列只能有一个线程池阻塞等待。 　　
		根据”“中分析的execute()代码可知：线程池中共运行了2个任务。
		第1个任务直接放到Worker中，通过线程去执行；第2个任务放到阻塞队列中等待。其他的任务都被丢弃了！
         */
        pool.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());  

        // 新建10个任务，并将它们添加到线程池中。  
        for (int i = 0; i < 10; i++) {  
            Runnable myrun = new MyRunnable("task-" + i);
            pool.execute(myrun);  
        }  
        // 关闭线程池  
        pool.shutdown();  
    }
    
    
    /**
     * (丢弃队列最前面的任务，然后重新尝试执行任务（重复此过程）)
     */
    public void discardOldestPolicy() {
    	final int THREADS_SIZE = 1;  
        final int CAPACITY = 1;  


        // 创建线程池。线程池的"最大池大小"和"核心池大小"都为1(THREADS_SIZE)，"线程池"的阻塞队列容量为1(CAPACITY)。  
        ThreadPoolExecutor pool = new ThreadPoolExecutor(THREADS_SIZE, THREADS_SIZE, 0, TimeUnit.SECONDS,  
                new ArrayBlockingQueue<Runnable>(CAPACITY));  
        // 设置线程池的拒绝策略为"DiscardOldestPolicy"  
        pool.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());  

        // 新建10个任务，并将它们添加到线程池中。  
        for (int i = 0; i < 10; i++) {  
            Runnable myrun = new MyRunnable("task-" + i);
            pool.execute(myrun);  
        }  
        // 关闭线程池  
        pool.shutdown();  
    }
    
    
    
    
    /**
     * 4.CallerRunsPolicy 示例(由调用线程处理该任务)
     * 将”线程池的拒绝策略”由DiscardPolicy修改为CallerRunsPolicy之后，
     * 当有任务添加到线程池被拒绝时，线程池会将被拒绝的任务添加到”线程池正在运行的线程”中取运行。
     */
    public void callerRunsPolicyDemo() {  

        final int THREADS_SIZE = 1;  
        final int CAPACITY = 1;  


        // 创建线程池。线程池的"最大池大小"和"核心池大小"都为1(THREADS_SIZE)，"线程池"的阻塞队列容量为1(CAPACITY)。  
        ThreadPoolExecutor pool = new ThreadPoolExecutor(THREADS_SIZE, THREADS_SIZE, 0, TimeUnit.SECONDS,  
                new ArrayBlockingQueue<Runnable>(CAPACITY));  
        // 设置线程池的拒绝策略为"CallerRunsPolicy"  
        pool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());  

        // 新建10个任务，并将它们添加到线程池中。  
        for (int i = 0; i < 10; i++) {  
            Runnable myrun = new MyRunnable("task-" + i);
            pool.execute(myrun);  
        }

        // 关闭线程池  
        pool.shutdown();  
        
    }




    static class MyRunnable implements Runnable {
	    private String name;  
	    public MyRunnable(String name) {  
	        this.name = name;  
	    }  
	    @Override  
	    public void run() {  
	        try {  
	            System.out.println(this.name + " is running.");  
	            Thread.sleep(1000);  
	        } catch (Exception e) {
	            e.printStackTrace();  
	        }  
	    }  
	}
	
	
	
	
}



